require "json"
require_relative "rpgxp-data"

def fade(obj)
  case obj
  when String
    obj.force_encoding("utf-8")
  when Integer, Float, TrueClass, FalseClass, NilClass
    return obj
  when Array
    obj.collect { |e| fade(e) }
  when Hash
    h = {}
    obj.each_pair do |k, v|
      h[k] = fade(v)
    end
    h
  else
    h = {}
    obj.instance_variables.each do |key|
      v = obj.instance_variable_get(key)
      k = key.to_s[1..-1]
      h[k] = fade(v)
    end
    h
  end
end

def _render(obj, data)
  case obj
  when String
    obj = data.force_encoding("ascii-8bit")
  when Integer, Float, TrueClass, FalseClass, NilClass
    obj = data
  when Array
    klass = obj.compact[0].class
    data.size.times do |i|
      if data[i].is_a?(Hash) && obj[i] == nil
        obj[i] = _render(klass.new, data[i])
      else
        obj[i] = _render(obj[i], data[i])
      end
    end
  when Hash
    data.keys.each { |i| obj[i] = _render(obj[i], data[i]) }
  else
    obj.instance_variables.each do |key|
      v = obj.instance_variable_get(key)
      k = key.to_s[1..-1]
      value = _render(v, data[k])
      obj.instance_variable_set(key, value)
    end
  end

  if obj.is_a? Table
    obj.instance_variable_set(:@size, (obj.zsize != 1) ? 3 : (obj.ysize != 1) ? 2 : 1)
  end

  obj
end

def render(klass, data)
  case data
  when String, Integer, Float, TrueClass, FalseClass, NilClass
    data
  when Array
    data.collect { |d| render(klass, d) }
  else
    _render(klass.new, data)
  end
end
